package network

import (
	"context"
	"fmt"
	"io"
	"log"
	"net"
	"os"

	"distcompiler/common"

	. "github.com/ahmetb/go-linq/v3"
)

func SendFile(conn net.Conn, file_path string) {
	file, err := os.Open(file_path)
	if err != nil {
		log.Print(err)
		return
	}
	defer file.Close()

	_, err = io.Copy(conn, file)
	if err != nil && err != io.EOF {
		log.Print(err)
	}
}
func ReceiveFile(conn net.Conn, file_path string) {
	var file *os.File
	_, err := os.Stat(file_path)
	if err == nil {
		file, err = os.Open(file_path)
		if err != nil {
			log.Print(err)
			return
		}
	} else {
		file, err = os.Create(file_path)
		if err != nil {
			log.Print(err)
			return
		}
	}
	defer file.Close()

	_, err = io.Copy(file, conn)
	if err != nil && err != io.EOF {
		log.Print(err)
	}
}

func TcpRun() {
	l := common.GetListenConfig()
	listener, err := l.Listen(context.Background(), "tcp", ":"+fmt.Sprint(Port))
	if err != nil {
		log.Print("listen error")
	}
	for {
		_, err := listener.Accept()
		if err != nil {
			log.Fatal(err)
		}
	}
}
func ReceiveData(con net.Conn) {
	start := uint(0)
	buf_data := make([]byte, 1024)
	for {
		n, err := con.Read(buf_data[start:])
		if err != nil {
			DeleteConn(con)
			break
		}

		for n > 6 {
			if buf_data[0] == 0xFA && buf_data[1] == 0xFB {
				start = uint(common.Byte2Int(buf_data[2:6]))
				if start <= uint(n) {
					ReceiveChatData(Byte2Pack(buf_data[6:start]))
					buf_data = append(buf_data[start:], buf_data[:start]...)
					n = n - int(start)
				} else {
					break
				}
			} else {
				buf_data = append(buf_data[2:], buf_data[:2]...)
				n = n - 2
			}
		}
		start = uint(n) //拆包解包
	}
}
func SendData(target string, data []byte) error {
	var send_data []byte
	send_data = append(send_data, 0xfa, 0xfb)
	send_data = append(send_data, common.Int2Byte(uint32(len(data)+6))...)
	send_data = append(send_data, data...)
	Server_list.lock.Lock()
	_, err := From(Server_list.servers).Where(func(i interface{}) bool {
		return i.(net.Conn).RemoteAddr().String() == target
	}).First().(net.Conn).Write(send_data)
	Server_list.lock.Unlock()
	return err
}
